
#if !defined (_JSON_VALUE_H)
#define _JSON_VALUE_H

#define _STD_STR_ 1

#if defined (_STD_STR_)
#	include <string>
	typedef std::string str;
#else
#	include "json_str.h"
	typedef json::string str;
#endif

/*

Need to comment about internal formats

*/

namespace json
{
	enum type
	{
	   null = 0x00,
	   object = 0x01,
	   array = 0x02,
	   number = 0x04,
	   string = 0x08,
	   boolean = 0x10,
	};

	class value
	{

	public:

		value(void);
		value(bool);
		value(float);
		value(const char *);
		value(const str &);
		value(const char *, const value &);
		value(const str &, const value &);
		value(const value &);
		~value(void);

		operator bool(void);
		operator str(void);
		operator const char *(void);
		operator float(void);

		value & operator =(bool);
		value & operator =(float);
		value & operator =(const char *);
		value & operator =(const str &);
		value & operator =(const value &);

		value & operator [](int);
		value & operator [](const char *);
		value & operator [](const str &);

		int add(const char *, const value &);
		int add(const str &, const value &);

		int add(const value &);

		int count(void) const;

		value & firstChild(void);
		value & next(void);

		str & keyAt(int);
		value & valueAt(int);

		bool containsKey(const char *);
		bool containsKey(const str &);

		inline bool isNull(void) const { return _type == null; }
		inline bool isBoolean(void) const { return _type == boolean; }
		inline bool isNumber(void) const { return _type == number; }
		inline bool isString(void) const { return _type == string; }
		inline bool isObject(void) const { return _type == object; }
		inline bool isArray(void) const { return _type == array; }

		value & toArray(void);
		value & toObject(void);

	private:

		static value _null;

		inline void _mem_assert(unsigned int req) 
		{ 
			if (_allocated < req) 
			{
				_data = (int*)realloc(_data, req + 4);
				_allocated = req;
			}
		}
		static inline void _mem_copy(int * src, int * dest, unsigned int count)
		{
			int count4 = count / 4;
			for (int i = 0; i < count4; ++i) dest[i] = src[i];
		}
		void _convertTo(type);

		type _type;
		unsigned int _allocated;
		int * _data;

	};

}

#endif